package com.situ.day21.reflect;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class ReflectDemo {

    @Test
    public void testClass() throws ClassNotFoundException {
        //1. Class.forName("完整的包名+类名")
        Class clazz1 = Class.forName("com.situ.day21.reflect.Student");
        //2. 类型.class
        Class clazz2 = Student.class;
        //3. 对象.getClass()
        Student student = new Student();
        Class clazz3 = student.getClass();

        System.out.println(clazz1 == clazz2);//true
        System.out.println(clazz1 == clazz3);//true
        System.out.println(clazz2 == clazz3);//true
    }

    @Test
    public void testConstructor1() {
        Class clazz = Student.class;
        //Declared:声明，只要是声明的，不管是private还是public都可以获取到
        Constructor[] constructors = clazz.getDeclaredConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
            System.out.println(constructor.getName());//构造方法的名字
            System.out.println(constructor.getModifiers());//构造方法修饰符: public private
        }
    }

    @Test
    public void testConstructor2() {
        Class clazz = Student.class;
        //只能获取public构造方法
        Constructor[] constructors = clazz.getConstructors();
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
            System.out.println(constructor.getName());
        }
    }

    @Test
    public void testConstructor3() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class clazz = Student.class;
        Constructor constructor = clazz.getDeclaredConstructor(String.class);
        // private Student(String name)
        //Student student = new Student("zhangsan");
        //java.lang.IllegalAccessException: Class com.situ.day21.reflect.ReflectDemo can not access a member of class com.situ.day21.reflect.Student with modifiers "private"
        //告诉调用者我是私有，但是你确实要用也行，就加上下面这句话
        constructor.setAccessible(true);
        Student student = (Student) constructor.newInstance("zhangsan");
        System.out.println(student);
    }

    @Test
    public void testMethod() throws NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        Class clazz = Student.class;
        Method method = clazz.getDeclaredMethod("setName", String.class);
        //这个方法是实例方法，所以还要new一个对象
        Student student = (Student) clazz.newInstance();
        method.setAccessible(true);
        method.invoke(student, "zhangsan");
        System.out.println(student);

        //Student student = new Student();
        //student.setName("zhangsan");
    }
}
